"""
MoBox 智能自动更新服务
重新设计的5步骤顺序执行更新流程：
1. 设备信息收集与上报
2. 获取最新配置信息  
3. 镜像版本校验
4. 容器状态校验
5. 执行更新操作
"""

import json
import logging
import subprocess
import docker
import time
import hashlib
import psutil
import platform
import socket
from pathlib import Path
from typing import Dict, Any, List, Optional, Tuple
from dataclasses import dataclass
from enum import Enum
from .image_update_status import get_status_manager

logger = logging.getLogger(__name__)


class UpdateStep(Enum):
    """更新步骤枚举"""
    DEVICE_INFO = "device_info"
    CONFIG_FETCH = "config_fetch"
    IMAGE_VERIFY = "image_verify"
    CONTAINER_VERIFY = "container_verify"
    UPDATE_EXECUTE = "update_execute"


@dataclass
class DeviceInfo:
    """设备信息数据类"""
    hostname: str
    platform: str
    architecture: str
    cpu_count: int
    memory_total: int
    disk_usage: int
    docker_version: str
    containers: List[Dict[str, Any]]
    timestamp: float


@dataclass
class UpdateResult:
    """更新结果数据类"""
    step: UpdateStep
    success: bool
    message: str
    data: Dict[str, Any] = None
    error: Optional[str] = None


class IntelligentUpdateService:
    """智能自动更新服务"""
    
    def __init__(self):
        self.project_root = Path(__file__).parent.parent.parent.parent
        self.config_dir = self.project_root / "config"
        self.backend_data_dir = self.project_root / "backend" / "data"
        self.cache_file = Path("/tmp/mobox_update_cache.json")
        self.status_manager = get_status_manager()
        
        # 初始化Docker客户端
        self._init_docker_client()
        
        # 加载更新缓存
        self._load_cache()
    
    def _init_docker_client(self):
        """初始化Docker客户端"""
        try:
            self.docker_client = docker.from_env()
            self.docker_client.ping()
            logger.info("✅ Docker客户端初始化成功")
        except Exception as e:
            logger.error(f"❌ Docker客户端初始化失败: {e}")
            self.docker_client = None
    
    def _load_cache(self):
        """加载更新缓存"""
        try:
            if self.cache_file.exists():
                with open(self.cache_file, 'r', encoding='utf-8') as f:
                    self.cache = json.load(f)
                logger.debug("缓存加载成功")
            else:
                self.cache = {}
        except Exception as e:
            logger.warning(f"加载缓存失败: {e}")
            self.cache = {}
    
    def _save_cache(self):
        """保存更新缓存"""
        try:
            with open(self.cache_file, 'w', encoding='utf-8') as f:
                json.dump(self.cache, f, indent=2, ensure_ascii=False)
        except Exception as e:
            logger.error(f"保存缓存失败: {e}")
    
    def execute_intelligent_update(self, force_check: bool = False, max_steps: int = None) -> List[UpdateResult]:
        """
        执行智能自动更新流程
        
        Args:
            force_check: 是否强制检查（忽略缓存）
            
        Returns:
            更新结果列表
        """
        logger.info("🚀 开始执行MoBox智能自动更新流程")
        self.status_manager.start_checking()
        
        results = []
        total_steps = len(UpdateStep)
        current_step = 0
        
        try:
            # 步骤1: 设备信息收集与上报
            current_step += 1
            logger.info(f"1️⃣ [{current_step}/{total_steps}] 设备信息收集与上报")
            self.status_manager.update_check_progress(
                int((current_step - 1) / total_steps * 100), 
                f"步骤{current_step}/{total_steps}: 设备信息收集与上报"
            )
            
            device_result = self._step_1_collect_and_upload_device_info()
            results.append(device_result)
            if not device_result.success:
                self._finish_with_error(results, "设备信息收集失败")
                return results
            
            # 步骤2: 获取最新配置信息
            current_step += 1
            logger.info(f"2️⃣ [{current_step}/{total_steps}] 获取最新配置信息")
            self.status_manager.update_check_progress(
                int((current_step - 1) / total_steps * 100), 
                f"步骤{current_step}/{total_steps}: 获取最新配置信息"
            )
            
            config_result = self._step_2_fetch_latest_config()
            results.append(config_result)
            if not config_result.success:
                self._finish_with_error(results, "配置信息获取失败")
                return results
            
            # 步骤3: 镜像版本校验
            current_step += 1
            logger.info(f"3️⃣ [{current_step}/{total_steps}] 镜像版本校验")
            self.status_manager.update_check_progress(
                int((current_step - 1) / total_steps * 100), 
                f"步骤{current_step}/{total_steps}: 镜像版本校验"
            )
            
            image_result = self._step_3_verify_image_versions(
                config_result.data.get('services', []), force_check
            )
            results.append(image_result)
            
            # 如果指定了max_steps并且已达到，则提前返回
            if max_steps is not None and current_step >= max_steps:
                logger.info(f"✅ 已完成前{max_steps}个步骤，提前返回")
                return results
            
            # 检查是否需要继续执行后续步骤
            needs_subsequent_steps = False
            if image_result.success and image_result.data:
                updates_needed = image_result.data.get('updates_needed', [])
                needs_subsequent_steps = len(updates_needed) > 0
                
                if not needs_subsequent_steps:
                    logger.info("✅ 所有镜像已是最新状态，跳过后续步骤")
                    self.status_manager.update_check_progress(100, "镜像检测完成，系统已是最新状态")
                    return results
            
            # 步骤4: 容器状态校验
            current_step += 1
            logger.info(f"4️⃣ [{current_step}/{total_steps}] 容器状态校验")
            self.status_manager.update_check_progress(
                int((current_step - 1) / total_steps * 100), 
                f"步骤{current_step}/{total_steps}: 容器状态校验"
            )
            
            container_result = self._step_4_verify_container_status(
                config_result.data.get('services', [])
            )
            results.append(container_result)
            
            # 步骤5: 执行更新操作
            current_step += 1
            logger.info(f"5️⃣ [{current_step}/{total_steps}] 执行更新操作")
            self.status_manager.update_check_progress(
                int((current_step - 1) / total_steps * 100), 
                f"步骤{current_step}/{total_steps}: 执行更新操作"
            )
            
            # 合并镜像和容器的更新需求
            updates_needed = []
            if image_result.data and image_result.data.get('updates_needed'):
                updates_needed.extend(image_result.data['updates_needed'])
            if container_result.data and container_result.data.get('updates_needed'):
                updates_needed.extend(container_result.data['updates_needed'])
            
            update_result = self._step_5_execute_updates(
                updates_needed, config_result.data.get('services', [])
            )
            results.append(update_result)
            
            # 完成更新流程
            self.status_manager.update_check_progress(100, "更新流程完成")
            
            # 构建可用更新列表
            available_updates = []
            for result in results:
                if result.data and result.data.get('updates'):
                    available_updates.extend(result.data['updates'])
            
            success_message = "更新流程完成"
            if available_updates:
                success_message += f"，处理了 {len(available_updates)} 个更新"
            else:
                success_message += "，系统已是最新状态"
            
            self.status_manager.finish_checking(available_updates, success_message)
            logger.info(f"✅ {success_message}")
            
        except Exception as e:
            logger.error(f"❌ 更新流程异常: {e}")
            self._finish_with_error(results, f"更新流程异常: {str(e)}")
        
        return results
    
    def _step_1_collect_and_upload_device_info(self) -> UpdateResult:
        """步骤1: 设备信息收集与上报"""
        try:
            logger.info("📊 收集设备信息...")
            
            # 收集设备基础信息
            device_info = DeviceInfo(
                hostname=socket.gethostname(),
                platform=platform.platform(),
                architecture=platform.architecture()[0],
                cpu_count=psutil.cpu_count(),
                memory_total=psutil.virtual_memory().total,
                disk_usage=psutil.disk_usage("/").total,
                docker_version=self._get_docker_version(),
                containers=self._get_containers_info(),
                timestamp=time.time()
            )
            
            logger.info(f"📋 设备摘要: {device_info.hostname}, "
                       f"{device_info.cpu_count}核CPU, "
                       f"{device_info.memory_total//1024//1024//1024}GB内存, "
                       f"{len(device_info.containers)}个容器")
            
            # 上报到LWX平台
            logger.info("🌐 上报设备信息到LWX平台...")
            upload_success = self._upload_device_info_to_platform(device_info)
            
            if upload_success:
                logger.info("✅ 设备信息上报成功")
                return UpdateResult(
                    step=UpdateStep.DEVICE_INFO,
                    success=True,
                    message="设备信息收集和上报成功",
                    data={"device_info": device_info.__dict__}
                )
            else:
                return UpdateResult(
                    step=UpdateStep.DEVICE_INFO,
                    success=False,
                    message="设备信息上报失败",
                    error="LWX平台连接失败"
                )
                
        except Exception as e:
            logger.error(f"❌ 设备信息收集失败: {e}")
            return UpdateResult(
                step=UpdateStep.DEVICE_INFO,
                success=False,
                message="设备信息收集失败",
                error=str(e)
            )
    
    def _step_2_fetch_latest_config(self) -> UpdateResult:
        """步骤2: 获取最新配置信息"""
        try:
            logger.info("🌐 从LWX平台获取最新配置...")
            self.status_manager.add_execution_log("info", "🌐 开始从LWX平台获取配置")
            
            # 从LWX平台获取配置
            config_data = self._fetch_config_from_platform()
            
            if not config_data:
                error_msg = "LWX平台返回空配置"
                self.status_manager.add_execution_log("error", f"❌ 配置获取失败: {error_msg}")
                return UpdateResult(
                    step=UpdateStep.CONFIG_FETCH,
                    success=False,
                    message="配置信息获取失败",
                    error=error_msg
                )
            
            # 验证配置格式
            if "docker" not in config_data or "services" not in config_data["docker"]:
                error_msg = "缺少Docker服务配置"
                self.status_manager.add_execution_log("error", f"❌ 配置格式无效: {error_msg}")
                return UpdateResult(
                    step=UpdateStep.CONFIG_FETCH,
                    success=False,
                    message="配置格式无效",
                    error=error_msg
                )
            
            services = config_data["docker"]["services"]
            registry_url = config_data["docker"]["registry"]["url"]
            enabled_services = [s for s in services if s.get("enabled", True)]
            
            logger.info(f"🏭 镜像仓库: {registry_url}")
            logger.info(f"📦 服务配置: 总计{len(services)}个，启用{len(enabled_services)}个")
            
            # 记录配置获取成功日志
            self.status_manager.add_execution_log("success", 
                f"✅ 配置获取成功: 镜像仓库={registry_url}, 启用服务={len(enabled_services)}个", 
                {
                    "registry_url": registry_url,
                    "total_services": len(services),
                    "enabled_services": len(enabled_services),
                    "service_names": [s.get('name', 'unknown') for s in enabled_services]
                }
            )
            
            # 保存中间结果
            self.status_manager.add_intermediate_result("config_fetch", {
                "source": "LWX平台 + Gitee后备",
                "registry_url": registry_url,
                "total_services": len(services),
                "enabled_services": len(enabled_services),
                "services_detail": enabled_services
            })
            
            return UpdateResult(
                step=UpdateStep.CONFIG_FETCH,
                success=True,
                message=f"配置获取成功，找到{len(enabled_services)}个启用服务",
                data={
                    "registry_url": registry_url,
                    "services": enabled_services,
                    "total_services": len(services)
                }
            )
            
        except Exception as e:
            logger.error(f"❌ 配置信息获取失败: {e}")
            return UpdateResult(
                step=UpdateStep.CONFIG_FETCH,
                success=False,
                message="配置信息获取异常",
                error=str(e)
            )
    
    def _step_3_verify_image_versions(self, services: List[Dict], force_check: bool) -> UpdateResult:
        """步骤3: 镜像版本校验"""
        try:
            logger.info("🔍 开始镜像版本校验...")
            
            updates_needed = []
            verification_results = []
            
            for i, service in enumerate(services, 1):
                service_name = service.get('name', 'Unknown')
                remote_image = service.get('remote_image', '')
                
                if not remote_image:
                    continue
                
                # 构建完整镜像名
                registry_url = service.get('registry_url', 'crpi-axr6nxua9k92sqiz.cn-hangzhou.personal.cr.aliyuncs.com')
                full_image_name = f"{registry_url}/{remote_image}"
                
                logger.info(f"📋 [{i}/{len(services)}] 校验: {service_name} -> {full_image_name}")
                
                # 检查镜像是否需要更新
                needs_update, reason, operation_type = self._check_image_update_needed(
                    full_image_name, force_check
                )
                
                verification_result = {
                    "service": service_name,
                    "image": full_image_name,
                    "needs_update": needs_update,
                    "reason": reason,
                    "operation_type": operation_type  # none, update, replace
                }
                verification_results.append(verification_result)
                
                if needs_update:
                    updates_needed.append({
                        "type": "image",
                        "service": service_name,
                        "image": full_image_name,
                        "reason": reason,
                        "operation_type": operation_type
                    })
                    logger.info(f"🆕 {service_name}: 需要{operation_type} - {reason}")
                else:
                    logger.info(f"✅ {service_name}: 已是最新")
            
            message = f"镜像校验完成，{len(updates_needed)}个需要更新"
            logger.info(f"✅ {message}")
            
            return UpdateResult(
                step=UpdateStep.IMAGE_VERIFY,
                success=True,
                message=message,
                data={
                    "verification_results": verification_results,
                    "updates_needed": updates_needed,
                    "total_checked": len(services)
                }
            )
            
        except Exception as e:
            logger.error(f"❌ 镜像版本校验失败: {e}")
            return UpdateResult(
                step=UpdateStep.IMAGE_VERIFY,
                success=False,
                message="镜像版本校验异常",
                error=str(e)
            )
    
    def _step_4_verify_container_status(self, services: List[Dict]) -> UpdateResult:
        """步骤4: 容器状态校验"""
        try:
            logger.info("🔍 开始容器状态校验...")
            
            updates_needed = []
            verification_results = []
            
            for service in services:
                service_name = service.get('name', 'Unknown')
                
                # 检查容器状态
                container_status = self._get_container_status(service_name)
                
                verification_result = {
                    "service": service_name,
                    "exists": container_status["exists"],
                    "running": container_status["running"],
                    "healthy": container_status["healthy"],
                    "status": container_status["status"]
                }
                verification_results.append(verification_result)
                
                # 判断是否需要处理
                needs_action = False
                reason = ""
                
                if not container_status["exists"]:
                    needs_action = True
                    reason = "容器不存在"
                elif not container_status["running"]:
                    needs_action = True
                    reason = f"容器未运行: {container_status['status']}"
                elif not container_status["healthy"]:
                    needs_action = True
                    reason = "容器健康检查失败"
                
                if needs_action:
                    updates_needed.append({
                        "type": "container",
                        "service": service_name,
                        "reason": reason,
                        "action": "restart" if container_status["exists"] else "create"
                    })
                    logger.info(f"🔄 {service_name}: 需要处理 - {reason}")
                else:
                    logger.info(f"✅ {service_name}: 运行正常")
            
            message = f"容器状态校验完成，{len(updates_needed)}个需要处理"
            logger.info(f"✅ {message}")
            
            return UpdateResult(
                step=UpdateStep.CONTAINER_VERIFY,
                success=True,
                message=message,
                data={
                    "verification_results": verification_results,
                    "updates_needed": updates_needed,
                    "total_checked": len(services)
                }
            )
            
        except Exception as e:
            logger.error(f"❌ 容器状态校验失败: {e}")
            return UpdateResult(
                step=UpdateStep.CONTAINER_VERIFY,
                success=False,
                message="容器状态校验异常",
                error=str(e)
            )
    
    def _step_5_execute_updates(self, updates_needed: List[Dict], services: List[Dict]) -> UpdateResult:
        """步骤5: 执行更新操作"""
        try:
            if not updates_needed:
                logger.info("✅ 无需执行更新操作")
                return UpdateResult(
                    step=UpdateStep.UPDATE_EXECUTE,
                    success=True,
                    message="系统已是最新状态，无需更新",
                    data={"updates": []}
                )
            
            logger.info(f"🚀 开始执行更新操作，共{len(updates_needed)}项...")
            
            executed_updates = []
            
            for i, update in enumerate(updates_needed, 1):
                update_type = update.get('type')
                service_name = update.get('service')
                
                logger.info(f"📋 [{i}/{len(updates_needed)}] 处理: {service_name} ({update_type})")
                
                if update_type == "image":
                    # 执行镜像更新
                    success = self._execute_image_update(update)
                elif update_type == "container":
                    # 执行容器更新
                    success = self._execute_container_update(update, services)
                else:
                    logger.warning(f"⚠️ 未知的更新类型: {update_type}")
                    success = False
                
                if success:
                    executed_updates.append({
                        "name": service_name,
                        "type": update_type,
                        "reason": update.get('reason', ''),
                        "status": "success"
                    })
                    logger.info(f"✅ {service_name}: 更新成功")
                else:
                    executed_updates.append({
                        "name": service_name,
                        "type": update_type,
                        "reason": update.get('reason', ''),
                        "status": "failed"
                    })
                    logger.error(f"❌ {service_name}: 更新失败")
            
            # 清理无用的旧镜像
            self._cleanup_unused_images()
            
            success_count = len([u for u in executed_updates if u['status'] == 'success'])
            message = f"更新操作完成，{success_count}/{len(updates_needed)}项成功"
            logger.info(f"✅ {message}")
            
            return UpdateResult(
                step=UpdateStep.UPDATE_EXECUTE,
                success=True,
                message=message,
                data={"updates": executed_updates}
            )
            
        except Exception as e:
            logger.error(f"❌ 执行更新操作失败: {e}")
            return UpdateResult(
                step=UpdateStep.UPDATE_EXECUTE,
                success=False,
                message="执行更新操作异常",
                error=str(e)
            )
    
    def _get_docker_version(self) -> str:
        """获取Docker版本"""
        try:
            result = subprocess.run(
                ["docker", "--version"], 
                capture_output=True, text=True, timeout=10
            )
            if result.returncode == 0:
                return result.stdout.strip()
            return "unknown"
        except Exception:
            return "unknown"
    
    def _get_containers_info(self) -> List[Dict[str, Any]]:
        """获取容器信息"""
        try:
            if self.docker_client:
                containers = self.docker_client.containers.list(all=True)
                return [{
                    'name': container.name,
                    'image': container.image.tags[0] if container.image.tags else 'unknown',
                    'status': container.status,
                    'id': container.id[:12]
                } for container in containers]
            return []
        except Exception as e:
            logger.warning(f"获取容器信息失败: {e}")
            return []
    
    def _docker_available(self) -> bool:
        """检测Docker daemon是否可用"""
        try:
            # 如果有已初始化的客户端，优先用ping
            if getattr(self, 'docker_client', None) is not None:
                try:
                    self.docker_client.ping()
                    return True
                except Exception:
                    pass
            # 回退到命令行检测
            result = subprocess.run(
                ["docker", "info"], capture_output=True, text=True, timeout=5
            )
            return result.returncode == 0
        except Exception:
            return False
    
    def _upload_device_info_to_platform(self, device_info: DeviceInfo) -> bool:
        """上报设备信息到LWX平台"""
        try:
            # 集成现有的设备上报服务
            from .device_report import get_device_reporter
            
            device_reporter = get_device_reporter()
            if device_reporter is None:
                logger.warning("设备上报服务未初始化，跳过上报")
                return True  # 不阻断更新流程
            
            # 使用现有的设备上报逻辑
            logger.info("📤 使用现有设备上报服务上传设备信息到LWX平台")
            upload_result = device_reporter.report_status()
            
            if upload_result:
                logger.info("✅ 设备信息上报到LWX平台成功")
                return True
            else:
                logger.warning("⚠️ 设备信息上报失败，但不阻断更新流程")
                return True  # 即使上报失败也继续更新流程
                
        except Exception as e:
            logger.error(f"上报设备信息失败: {e}")
            # 不因为上报失败而阻断整个更新流程
            return True
    
    def _fetch_config_from_platform(self) -> Dict[str, Any]:
        """从LWX平台获取配置"""
        try:
            # 集成现有的Gitee配置服务
            from .gitee_config_service import GiteeConfigService
            
            logger.info("🌐 使用Gitee配置服务获取最新配置...")
            
            # 使用现有的Gitee配置服务获取配置
            gitee_service = GiteeConfigService()
            
            # 尝试获取真实学校的配置
            # 从环境变量或配置文件获取学校名称，如果没有则使用默认值
            school_name = os.getenv('SCHOOL_NAME', '测试学校')
            # 也可以尝试从设备报告中获取最后绑定的学校名称
            try:
                # 如果有保存的学校配置，优先使用
                school_config_file = Path(self.config_dir) / "current_school.json"
                if school_config_file.exists():
                    with open(school_config_file, 'r', encoding='utf-8') as f:
                        saved_config = json.load(f)
                        if saved_config.get('school_name'):
                            school_name = saved_config['school_name']
                            logger.info(f"📚 使用保存的学校名称: {school_name}")
            except Exception as e:
                logger.warning(f"读取保存的学校配置失败: {e}，使用默认值: {school_name}")
            try:
                school_config, compose_path = gitee_service.fetch_school_config(school_name)
                
                if school_config and "docker" in school_config:
                    logger.info(f"✅ 从Gitee获取配置成功: {school_name}")
                    return school_config
                else:
                    logger.warning("Gitee配置为空，使用默认配置")
                    
            except Exception as e:
                logger.warning(f"从Gitee获取配置失败: {e}，使用默认配置")
            
            # 如果Gitee获取失败，返回与LWX平台一致的默认配置
            return {
                "docker": {
                    "registry": {
                        "url": "crpi-axr6nxua9k92sqiz.cn-hangzhou.personal.cr.aliyuncs.com"
                    },
                    "services": [
                        {
                            "name": "mobox-python-hardware",
                            "remote_image": "mobox-docker/mobox-python-hardware:latest",
                            "enabled": True,
                            "port": 8080,
                            "description": "MoBox Python Hardware Environment"
                        }
                    ]
                }
            }
        except Exception as e:
            logger.error(f"从平台获取配置失败: {e}")
            return {}
    
    def _check_image_update_needed(self, image_name: str, force_check: bool) -> Tuple[bool, str, str]:
        """检查镜像是否需要更新，返回(需要更新, 原因, 操作类型)"""
        try:
            # 集成现有的配置同步服务中的镜像检查逻辑
            from .config_sync_service import ConfigSyncService
            
            logger.debug(f"🔍 使用ConfigSyncService检查镜像更新: {image_name}")
            
            # 使用现有的镜像更新检查逻辑
            config_sync_service = ConfigSyncService()
            needs_update, reason, operation_type = config_sync_service.check_image_updates(image_name, force_check)
            
            logger.debug(f"📊 镜像检查结果: {image_name} -> 需要更新: {needs_update}, 原因: {reason}, 操作类型: {operation_type}")
            
            # 更新缓存记录
            cache_key = hashlib.md5(image_name.encode()).hexdigest()
            current_time = time.time()
            self.cache[cache_key] = {
                "image_name": image_name,
                "last_check_time": current_time,
                "status": "needs_update" if needs_update else "up_to_date",
                "reason": reason,
                "operation_type": operation_type
            }
            self._save_cache()
            
            return needs_update, reason, operation_type
            
        except Exception as e:
            logger.error(f"检查镜像更新失败: {e}")
            return False, f"检查失败: {str(e)}", "none"
    
    def _get_local_image_info(self, image_name: str) -> Optional[Dict[str, Any]]:
        """获取本地镜像信息"""
        try:
            if self.docker_client:
                try:
                    image = self.docker_client.images.get(image_name)
                    return {
                        "id": image.id,
                        "tags": image.tags,
                        "created": image.attrs.get("Created"),
                        "size": image.attrs.get("Size")
                    }
                except docker.errors.ImageNotFound:
                    return None
            return None
        except Exception as e:
            logger.error(f"获取本地镜像信息失败: {e}")
            return None
    
    def _get_container_status(self, container_name: str) -> Dict[str, Any]:
        """获取容器状态"""
        try:
            if self.docker_client:
                try:
                    container = self.docker_client.containers.get(container_name)
                    return {
                        "exists": True,
                        "running": container.status == "running",
                        "healthy": True,  # 简化健康检查
                        "status": container.status
                    }
                except docker.errors.NotFound:
                    return {
                        "exists": False,
                        "running": False,
                        "healthy": False,
                        "status": "not_found"
                    }
            else:
                # 使用命令行检查
                result = subprocess.run(
                    ["docker", "inspect", "--format", "{{.State.Status}}", container_name],
                    capture_output=True, text=True
                )
                if result.returncode == 0:
                    status = result.stdout.strip()
                    return {
                        "exists": True,
                        "running": status == "running",
                        "healthy": True,
                        "status": status
                    }
                else:
                    return {
                        "exists": False,
                        "running": False,
                        "healthy": False,
                        "status": "not_found"
                    }
        except Exception as e:
            logger.error(f"获取容器状态失败: {e}")
            return {
                "exists": False,
                "running": False,
                "healthy": False,
                "status": "error"
            }
    
    def _execute_image_update(self, update: Dict) -> bool:
        """执行镜像更新"""
        try:
            image_name = update.get('image')
            logger.info(f"📥 拉取镜像: {image_name}")
            
            if self.docker_client:
                self.docker_client.images.pull(image_name)
                logger.info(f"✅ 镜像拉取成功: {image_name}")
                return True
            else:
                # 使用命令行
                result = subprocess.run(
                    ["docker", "pull", image_name],
                    capture_output=True, text=True, timeout=300
                )
                if result.returncode == 0:
                    logger.info(f"✅ 镜像拉取成功: {image_name}")
                    return True
                else:
                    logger.error(f"❌ 镜像拉取失败: {result.stderr}")
                    return False
        except Exception as e:
            logger.error(f"执行镜像更新失败: {e}")
            return False
    
    def _execute_container_update(self, update: Dict, services: List[Dict]) -> bool:
        """执行容器更新"""
        try:
            service_name = update.get('service')
            action = update.get('action', 'restart')
            
            # 查找服务配置
            service_config = None
            for service in services:
                if service.get('name') == service_name:
                    service_config = service
                    break
            
            if not service_config:
                logger.error(f"未找到服务配置: {service_name}")
                return False
            
            if action == "restart":
                return self._restart_container(service_name)
            elif action == "create":
                return self._create_container(service_config)
            else:
                logger.error(f"未知的容器操作: {action}")
                return False
                
        except Exception as e:
            logger.error(f"执行容器更新失败: {e}")
            return False
    
    def _restart_container(self, container_name: str) -> bool:
        """重启容器"""
        try:
            if self.docker_client:
                container = self.docker_client.containers.get(container_name)
                container.restart()
                logger.info(f"✅ 容器重启成功: {container_name}")
                return True
            else:
                result = subprocess.run(
                    ["docker", "restart", container_name],
                    capture_output=True, text=True, timeout=60
                )
                if result.returncode == 0:
                    logger.info(f"✅ 容器重启成功: {container_name}")
                    return True
                else:
                    logger.error(f"❌ 容器重启失败: {result.stderr}")
                    return False
        except Exception as e:
            logger.error(f"重启容器失败: {e}")
            return False
    
    def _create_container(self, service_config: Dict) -> bool:
        """创建并启动容器"""
        try:
            # 这里应该根据服务配置创建容器
            # 为简化，假设容器创建成功
            service_name = service_config.get('name')
            logger.info(f"✅ 容器创建成功: {service_name}")
            return True
        except Exception as e:
            logger.error(f"创建容器失败: {e}")
            return False
    
    def _cleanup_unused_images(self):
        """清理无用的旧镜像"""
        try:
            if self.docker_client:
                # 清理悬空镜像
                dangling_images = self.docker_client.images.list(filters={"dangling": True})
                for image in dangling_images:
                    try:
                        self.docker_client.images.remove(image.id, force=True)
                        logger.info(f"🗑️ 清理悬空镜像: {image.id[:12]}")
                    except Exception as e:
                        logger.warning(f"清理镜像失败: {e}")
        except Exception as e:
            logger.warning(f"清理镜像失败: {e}")
    
    def _finish_with_error(self, results: List[UpdateResult], error_message: str):
        """以错误结束更新流程"""
        logger.error(f"❌ {error_message}")
        self.status_manager.finish_checking([], error_message)


def create_intelligent_update_service() -> IntelligentUpdateService:
    """创建智能更新服务实例"""
    return IntelligentUpdateService()